package com.cje.queryanddel;

import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.repository.ProcessDefinitionQuery;
import org.apache.commons.io.IOUtils;
import org.junit.Test;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;

/**
 * 删除已经部署的流程定义
 *
 * 背后影响的表:
 * act_ge_bytearray
   act_re_deployment
   act_re_procdef
 */
public class QueryAndDeleteProcessDefinition {

    /**
     * @Author: ChenJinEn
     * @Date: 2020/8/22 21:54
     * @params: []
     * @return: java.util.List<org.activiti.engine.repository.ProcessDefinition>
     * @Description: //TODO 查询流程定义信息
     */
    public List<ProcessDefinition> queryProcessDefine(){
        //1.得到ProcessEngine对象
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

        //2.创建RepositoryService对象
        RepositoryService repositoryService = processEngine.getRepositoryService();

        //3.得到ProcessDefinitionQuery对象,可以认为它就是一个查询器
        ProcessDefinitionQuery processDefinitionQuery = repositoryService
                .createProcessDefinitionQuery()
                .processDefinitionKey("holiday")
                .orderByProcessDefinitionVersion()
                .desc();

        //4.设置条件，并查询出当前的所有流程定义   查询条件：流程定义的key=holiday
        //orderByProcessDefinitionVersion() 设置排序方式,根据流程定义的版本号进行排序
        List<ProcessDefinition> list = processDefinitionQuery.list();

        //5.输出流程定义信息
        for(ProcessDefinition processDefinition :list){
            System.out.println("流程定义ID："+processDefinition.getId());
            System.out.println("流程定义名称："+processDefinition.getName());
            System.out.println("流程定义的Key："+processDefinition.getKey());
            System.out.println("流程定义的版本号："+processDefinition.getVersion());
            System.out.println("流程部署的ID:"+processDefinition.getDeploymentId());
        }
        return list;
    }


    @Test
    public void queryFile() throws IOException {
        //1.得到ProcessEngine对象
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

        //2.得到RepositoryService对象
        RepositoryService repositoryService = processEngine.getRepositoryService();

        //3.得到查询器:ProcessDefinitionQuery对象
        ProcessDefinitionQuery processDefinitionQuery = repositoryService
                .createProcessDefinitionQuery()
                .processDefinitionKey("holiday")
                .orderByProcessDefinitionVersion()
                .desc();

        //5.执行查询操作,查询出想要的流程定义
        List<ProcessDefinition> list = processDefinitionQuery.list();
        InputStream pngIs =null;
        InputStream bpmnIs =null;
        OutputStream pngOs =null;
        OutputStream bpmnOs =null;
        for (ProcessDefinition processDefinition : list) {
        //6.通过流程定义信息，得到部署ID
        String deploymentId = processDefinition.getDeploymentId();

        //7.通过repositoryService的方法,实现读取图片信息及bpmn文件信息(构建输入流)
        //getResourceAsStream()方法的参数说明：第一个参数部署id,第二个参数代表资源名称
        //processDefinition.getDiagramResourceName() 代表获取png图片资源的名称
        //processDefinition.getResourceName()代表获取bpmn文件的名称
        pngIs = repositoryService
                .getResourceAsStream(deploymentId,processDefinition.getDiagramResourceName());
        bpmnIs = repositoryService
                .getResourceAsStream(deploymentId,processDefinition.getResourceName());

        //8.构建出OutputStream流,代表文件输出到文件流的D:\demo的文件夹下
        pngOs = new FileOutputStream("D:\\demo\\"+processDefinition.getDiagramResourceName());
        bpmnOs = new FileOutputStream("D:\\demo\\"+processDefinition.getResourceName());

        //9.输入流，输出流的转换  commons-io-xx.jar中的方法
        IOUtils.copy(pngIs,pngOs);
        IOUtils.copy(bpmnIs,bpmnOs);
        }
        //10.关闭流
        pngOs.close();
        bpmnOs.close();
        pngIs.close();
        bpmnIs.close();

    }

    /**
     * @Author: ChenJinEn
     * @Date: 2020/8/22 21:55
     * @params: []
     * @return: void
     * @Description: //TODO 删除定义好的流程
     *
     * 注意事项：
     *     1.当我们正在执行的这一套流程没有完全审批结束的时候，此时如果要删除流程定义信息就会失败
     *     2.如果公司层面要强制删除,可以使用repositoryService.deleteDeployment("1",true);
     *     //参数true代表级联删除，此时就会先删除没有完成的流程结点，最后就可以删除流程定义信息  false的值代表不级联
     */
    @Test
    public void delProcessDefi() {
        //1.得到ProcessEngine对象
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

        //2.创建RepositoryService对象
        RepositoryService repositoryService = processEngine.getRepositoryService();

        //3.执行删除流程定义  参数代表流程部署的id
        for (ProcessDefinition processDefinition : queryProcessDefine()) {
        repositoryService.deleteDeployment(processDefinition.getDeploymentId(),true);
        }
    }
}
